package gy.com.sansharescuesystem.adapter;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.map.TextureMapView;
import com.baidu.mapapi.model.LatLng;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

import java.util.ArrayList;
import java.util.List;

import gy.com.sansharescuesystem.R;
import gy.com.sansharescuesystem.callback.AcyncCallBack;
import gy.com.sansharescuesystem.entity.HistoryOrbit;
import gy.com.sansharescuesystem.entity.HistoryOrbitData;
import gy.com.sansharescuesystem.entity.RescueListResData;
import gy.com.sansharescuesystem.entity.ShipBean;
import gy.com.sansharescuesystem.entity.ShipDataBean;
import gy.com.sansharescuesystem.fragment.BoatMessageDialog;
import gy.com.sansharescuesystem.modle.QueryModel;
import gy.com.sansharescuesystem.modle.impl.QueryModelImpl;
import gy.com.sansharescuesystem.utils.Constant;
import gy.com.sansharescuesystem.utils.DateUtil;
import gy.com.sansharescuesystem.utils.MapUtil;
import gy.com.sansharescuesystem.utils.UIUtils;
import gy.com.sansharescuesystem.widget.BatteryView;

/**
 * Created by 陈秋霖 on 2017-07-13.
 */

public class RescueAdapter extends BaseAdapter {
    private Context context;
    private Activity mActivity;
    private List<RescueListResData> resps;
    private int currentItem = -1;
    private PullToRefreshListView mListView;
    //百度地图相关 定位本机
    private SensorManager mSensorManager;
    private TextureMapView mMapView;
    private BaiduMap mBaiduMap;
    private boolean isFirstLoc = true;
    //计算距离用
    private static final int GET_LOCATION_DATA_BY_SN_SUCCESS = 1;
    private static final int GET_LOCATION_DATA_BY_SHIP_SUCCESS = 2;
    private static final int GET_LOCATION_DATA_BY_SN_FAILED = 3;
    private static final int GET_LOCATION_DATA_BY_SHIP_FAILED = 4;
    private static final int GET_SHIP_INFOR_SUCCESS = 5;
    private static final int GET_SHIP_INFOR_FAILED = 6;
    //判断是否分别获取了船只和求救人员的位置
    private boolean shipOrbitGet = false;
    private boolean SOSOrbitGet = false;
    //网络请求
    private QueryModel model = new QueryModelImpl();
    //Runnable
    private Runnable runnable;
    //救援船loc点数组
    private List<LatLng> mLocList = new ArrayList<>();
    //求救人loc点数组,每拿到一个坐标就clear一次地图，再加载所有的点
    private List<LatLng> mTargLocList = new ArrayList<>();
    //电池控件
    BatteryView mBatteryView;
    //电池电量
    TextView mBatteryText;
    //dialog
    final BoatMessageDialog boatMessageDialog = BoatMessageDialog.getInstance();
    //广播
    private RescueBroadcastReceiver mRescueReceiver = new RescueBroadcastReceiver();
    //flag
    private int pageFlage = 2;
    private boolean isMapOpen = false;
    //处理数据
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case GET_LOCATION_DATA_BY_SN_SUCCESS:
                    HistoryOrbit historyOrbit1 = (HistoryOrbit) msg.obj;
                    List<HistoryOrbitData> data1 = historyOrbit1.getData();
                    if (data1 != null) {
                        Log.i("info", "soslentgh = " + mTargLocList.size() + ",shipSize = " + mLocList.size());
                        //更新电池数据
                        if (mBatteryView != null && mBatteryText != null) {
                            float power = Float.parseFloat((data1.get(data1.size() - 1).getEnergy()));
                            if (power >= 100) {
                                power = 100;
                            }
                            mBatteryView.setPower(power);
                            mBatteryText.setText((data1.get(data1.size() - 1).getEnergy()) + "%");
                        }
                        //更新location
                        mTargLocList.clear();
                        for (int i = 0; i < data1.size(); i++) {
                            LatLng point = new LatLng(Double.parseDouble(data1.get(i).getLat())
                                    , Double.parseDouble(data1.get(i).getLog()));
                            mTargLocList.add(point);
                        }
                        Log.i("info", "size = " + mTargLocList.size());

                    } else {
                        UIUtils.showToast(context, "无求救人员轨迹数据");
                    }
                    SOSOrbitGet = true;
                    drawAllMarkers();
                    break;
                case GET_LOCATION_DATA_BY_SN_FAILED:
                    UIUtils.showToast(context, "根据sn查询失败");
                    break;
                case GET_LOCATION_DATA_BY_SHIP_SUCCESS:
                    HistoryOrbit historyOrbit = (HistoryOrbit) msg.obj;
                    List<HistoryOrbitData> data = historyOrbit.getData();
                    if (data != null) {
                        mLocList.clear();
                        for (int i = 0; i < data.size(); i++) {
                            LatLng point = new LatLng(Double.parseDouble(data.get(i).getLat())
                                    , Double.parseDouble(data.get(i).getLog()));
                            mLocList.add(point);
                        }
                    } else {
                        UIUtils.showToast(context, "无救援船只轨迹数据");
                    }
                    shipOrbitGet = true;
                    drawAllMarkers();
                    break;
                case GET_LOCATION_DATA_BY_SHIP_FAILED:
                    UIUtils.showToast(context, "根据ship查询失败");
                    break;
                case GET_SHIP_INFOR_SUCCESS:
                    ShipBean bean = (ShipBean) msg.obj;
                    List<ShipDataBean> shipDataBean = bean.getData();
                    boatMessageDialog.setData(shipDataBean.get(0));
                    break;
                case GET_SHIP_INFOR_FAILED:
                    UIUtils.showToast(context, "获取船只信息失败");
                    break;
            }
        }
    };

    private void drawAllMarkers() {
        if (SOSOrbitGet && shipOrbitGet) {
            Log.i("info", "SHIP = " + mLocList + ",SOS =" + mTargLocList);
            if (mLocList.size() > 0 && mTargLocList.size() > 0) {
                setLocation();
            } else {
                if (mLocList.size() > 0) {
                    moveToPoint(mLocList);
                } else if (mTargLocList.size() > 0) {
                    moveToPoint(mTargLocList);
                }
            }
            //画点和线
            upDataBothShipAndSn();
        }
    }

    private void moveToPoint(List<LatLng> list) {
        LatLng first = list.get(0);
        LatLng last = list.get(list.size() - 1);
        double distanse = MapUtil.getDistance(first.latitude, first.longitude, last.latitude, last.longitude);
        float zoom = MapUtil.getZoom(distanse);
        if (isFirstLoc) {
            isFirstLoc = false;
            LatLng ll = new LatLng((first.latitude + last.latitude) / 2, (first.longitude + last.longitude) / 2);
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(ll).zoom(zoom);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }
    }

    public RescueAdapter(Context context, List<RescueListResData> resps, PullToRefreshListView listView) {
        super();
        this.context = context;
        mActivity = (Activity) context;
        this.resps = resps;
        mListView = listView;
        //注册广播
        IntentFilter filter = new IntentFilter();
        filter.addAction(Constant.RESCUE_DESTROY);
        filter.addAction(Constant.RESCUE_PAUSE);
        filter.addAction(Constant.RESCUE_RESUME);
        filter.addAction(Constant.RESCUE_STOP);
        filter.addAction(Constant.TO_COUNT_PAGE);
        filter.addAction(Constant.TO_HISTORY_PAGE);
        filter.addAction(Constant.TO_RESCUE_PAGE);
        context.registerReceiver(mRescueReceiver, filter);
    }

    @Override
    public int getCount() {
        return resps.size();
    }

    @Override
    public Object getItem(int position) {
        return resps.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            SDKInitializer.initialize(context.getApplicationContext());
            convertView = LayoutInflater.from(context).inflate(R.layout.layout_expand_list_item, null);
            holder.showArea = (LinearLayout) convertView.findViewById(R.id.ll_show_area);
            holder.hideArea = (RelativeLayout) convertView.findViewById(R.id.rl_hide_area);
            holder.no = (TextView) convertView.findViewById(R.id.tv_no);
            holder.callNum = (TextView) convertView.findViewById(R.id.tv_call_num);
            holder.progressImage = (ImageView) convertView.findViewById(R.id.iv_rescue_pro_image);
            holder.progress = (ImageView) convertView.findViewById(R.id.iv_rescue_progress);
            holder.fallTime = (TextView) convertView.findViewById(R.id.tv_fall_time);
            holder.callTimes = (TextView) convertView.findViewById(R.id.tv_call_times);
            holder.endTime = (TextView) convertView.findViewById(R.id.tv_chujing_time);
            holder.machineNum = (TextView) convertView.findViewById(R.id.tv_machine_no);
            holder.goBack = (ImageButton) convertView.findViewById(R.id.iv_scroll_back);
            holder.mMap = (TextureMapView) convertView.findViewById(R.id.mv_map);
            holder.mBattery = (BatteryView) convertView.findViewById(R.id.battery);
            holder.mTvBattery = (TextView) convertView.findViewById(R.id.tv_battery);
            holder.mIbBoat = (ImageButton) convertView.findViewById(R.id.boat_message);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        final RescueListResData resp = resps.get(position);
        //为了记录点击的 position，用 position 设置 Tag
        holder.showArea.setTag(position);
        holder.goBack.setTag(position);

        holder.no.setText(position + 1 + "");
        holder.callNum.setText("报警编号：" + resp.getId());
        holder.fallTime.setText(DateUtil.getStringByFormat(Long.parseLong(resp.getC_time()) * 1000, "MM-dd HH:mm"));
        holder.endTime.setText(DateUtil.getStringByFormat(Long.parseLong(resp.getE_time()) * 1000, "MM-dd HH:mm"));
        holder.callTimes.setText(resp.getNum() + "次");
        holder.machineNum.setText(resp.getSerial());

        int status = Integer.parseInt(resp.getStatus());
        switch (status) {
            case 1:
                holder.progressImage.setImageResource(R.drawable.notice_light);
                holder.progress.setImageResource(R.drawable.baojing);
                break;
            case 2:
                holder.progressImage.setImageResource(R.drawable.star_light);
                holder.progress.setImageResource(R.drawable.jiejing);
                break;
            case 3:
                holder.progressImage.setImageResource(R.drawable.search);
                holder.progress.setImageResource(R.drawable.jiuyuan);
                break;
            default:
                holder.progressImage.setImageResource(R.drawable.search);
                holder.progress.setImageResource(R.drawable.jiuyuan);
        }
        /*
        * 根据 currentItem 记录的点击位置来设置"对应Item"的可见性
        * （在list依次加载列表数据时，每加载一个时都看一下是不是需改变可见性的那一条）
        * */
        if (currentItem == position) {
            holder.hideArea.setVisibility(View.VISIBLE);
            mMapView = holder.mMap;
            mBaiduMap = mMapView.getMap();
            //电池
            mBatteryView = holder.mBattery;
            mBatteryText = holder.mTvBattery;
            holder.mMap.onResume();
            holder.goBack.setOnClickListener(innerOnClickListener);
            //mapview中的子类消耗了这个touch事件，所以要改的是该子类
            View v = holder.mMap.getChildAt(0);
            v.setOnTouchListener(innerOnTouchListener);
            //快速切换时不走else
            isFirstLoc = true;
            mTargLocList.clear();
            mLocList.clear();
            mHandler.removeCallbacks(runnable);
            runnable = null;
            SOSOrbitGet = false;
            shipOrbitGet = false;
            //根据船只设备编号获取救援船轨迹
            final String ship = resp.getShip();
            if (ship != null) {
                getShipOrbit(ship);
            }
            //获取求救者轨迹
            final String serial = resp.getSerial();
            if (serial != null) {
                getSOSOrbit(serial);
            }
            if (runnable == null) {
                runnable = new Runnable() {
                    @Override
                    public void run() {
                        //获取救援船轨迹
                        if (ship != null && serial != null) {
                            getShipOrbit(ship);
                            //获取求救者轨迹
                            getSOSOrbit(serial);
                        }
                        mHandler.postDelayed(this, 5000);
                    }
                };
            }
            mHandler.postDelayed(runnable, 0);
        } else {
            //地图关闭的情况下才将runnable移除
            if (!isMapOpen) {
                if (mBaiduMap != null) {
                    mBaiduMap.clear();
                }
                if (mMapView != null) {
                    mMapView.onPause();
                }
                mHandler.removeCallbacks(runnable);
                runnable = null;
                SOSOrbitGet = false;
                shipOrbitGet = false;
                mBatteryView = null;
                mBatteryText = null;
            }
            holder.hideArea.setVisibility(View.GONE);
        }
        holder.showArea.setOnClickListener(innerOnClickListener);
        holder.mIbBoat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!boatMessageDialog.isAdded()) {
                    boatMessageDialog.show(mActivity.getFragmentManager(), "Boat_Message");
                }
                model.queryShipData(new AcyncCallBack() {
                    @Override
                    public void onSuccess(Object obj) {
                        if (obj != null) {
                            Message msg = mHandler.obtainMessage();
                            msg.what = GET_SHIP_INFOR_SUCCESS;
                            msg.obj = obj;
                            mHandler.sendMessage(msg);
                        } else {
                            mHandler.sendEmptyMessage(GET_SHIP_INFOR_FAILED);

                        }
                    }

                    @Override
                    public void onFailed() {
                        mHandler.sendEmptyMessage(GET_SHIP_INFOR_FAILED);
                    }
                }, resp.getSerial());
            }
        });
        return convertView;
    }

    private void getSOSOrbit(String serial) {
        model.queryRescueInfoBySn(new AcyncCallBack() {
            @Override
            public void onSuccess(Object obj) {
                Message msg = mHandler.obtainMessage();
                msg.what = GET_LOCATION_DATA_BY_SN_SUCCESS;
                msg.obj = obj;
                mHandler.sendMessage(msg);
            }

            @Override
            public void onFailed() {
                mHandler.sendEmptyMessage(GET_LOCATION_DATA_BY_SN_FAILED);
            }
        }, serial);
    }

    private void getShipOrbit(String ship) {
        model.queryRescueInfoByShip(new AcyncCallBack() {
            @Override
            public void onSuccess(Object obj) {
                Message msg = mHandler.obtainMessage();
                msg.what = GET_LOCATION_DATA_BY_SHIP_SUCCESS;
                msg.obj = obj;
                mHandler.sendMessage(msg);
            }

            @Override
            public void onFailed() {
                mHandler.sendEmptyMessage(GET_LOCATION_DATA_BY_SHIP_FAILED);
            }
        }, ship);
    }


    private CloseOnTouchListener innerOnTouchListener = new CloseOnTouchListener();

    class CloseOnTouchListener implements View.OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                mListView.getRefreshableView().requestDisallowInterceptTouchEvent(false);
            } else {
                mListView.getRefreshableView().requestDisallowInterceptTouchEvent(true);
            }
            return false;
        }
    }

    private InnerOnClickListener innerOnClickListener = new InnerOnClickListener();

    class InnerOnClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.ll_show_area:
                    int tag = (int) v.getTag();
                    if (tag == currentItem) {
                        currentItem = -1;
                        isMapOpen = false;
                    } else {
                        currentItem = tag;
                        isMapOpen = true;
                    }
                    notifyDataSetChanged();
                    break;
                case R.id.boat_message:

                    break;
            }
        }
    }

    private static class ViewHolder {
        private LinearLayout showArea;
        private RelativeLayout hideArea;
        private TextView no;
        private TextView callNum;
        private ImageView progressImage;
        private ImageView progress;
        private TextView fallTime;
        private TextView callTimes;
        private TextView endTime;
        private TextView machineNum;
        private ImageButton goBack;
        private TextureMapView mMap;
        private BatteryView mBattery;
        private TextView mTvBattery;
        private ImageButton mIbBoat;
    }

    private void setLocation() {
        //将两个初始位置的中心定位到地图中心位置
        double lat1 = mLocList.get(0).latitude;
        double lon1 = mLocList.get(0).longitude;
        double lat2 = mTargLocList.get(0).latitude;
        double lon2 = mTargLocList.get(0).longitude;
        double lat3 = mLocList.get(mLocList.size() - 1).latitude;
        double lon3 = mLocList.get(mLocList.size() - 1).longitude;
        double lat4 = mTargLocList.get(mTargLocList.size() - 1).latitude;
        double lon4 = mTargLocList.get(mTargLocList.size() - 1).longitude;
        double disFirst = MapUtil.getDistance(lat1, lon1, lat2, lon2);
        double disLast = MapUtil.getDistance(lat3, lon3, lat4, lon4);
        float zoom = 0;
        if (disFirst > disLast) {
            zoom = MapUtil.getZoom(disFirst);
        } else {
            zoom = MapUtil.getZoom(disLast);
        }
        double latLoc = (lat1 + lat2) / 2;
        double lonLoc = (lon1 + lon2) / 2;
        if (isFirstLoc) {
            isFirstLoc = false;
            LatLng point = new LatLng(latLoc, lonLoc);
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(point).zoom(zoom);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }
    }

    private void upDataBothShipAndSn() {
        mBaiduMap.clear();
        addMarkersForShip();
        addMarkersForSOS();
    }

    private void addMarkersForShip() {
        if (mLocList != null && mLocList.size() > 0) {
            double preLat = mLocList.get(0).latitude;
            double preLon = mLocList.get(0).longitude;
            for (int i = 0; i < mLocList.size() - 1; i++) {
                LatLng point = mLocList.get(i);
                LatLng nextP = mLocList.get(i + 1);
                float direction = MapUtil.getDirection(point, nextP);
                OverlayOptions options = new MarkerOptions().position(point).icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow_b_up));
                Marker marker = (Marker) mBaiduMap.addOverlay(options);
                marker.setAnchor(0.5f, 0.5f);
                marker.setRotate(direction);
//                drawLine(preLat,preLon,point.latitude,point.longitude,0xff004db0);
//                preLat = point.latitude;
//                preLon = point.longitude;
                drawLine(preLat, preLon, nextP.latitude, nextP.longitude, 0xff004db0);
                preLat = nextP.latitude;
                preLon = nextP.longitude;
            }
            LatLng point = mLocList.get(mLocList.size() - 1);
            OverlayOptions options = new MarkerOptions().position(point).icon(BitmapDescriptorFactory.fromResource(R.drawable.origin));
            Marker marker = (Marker) mBaiduMap.addOverlay(options);
            marker.setAnchor(0.5f, 0.5f);
            drawLine(preLat, preLon, point.latitude, point.longitude, 0xff004db0);
        }
    }

    private void addMarkersForSOS() {
        if (mTargLocList != null && mTargLocList.size() > 0) {
            double preTargLat = mTargLocList.get(0).latitude;
            double preTargLon = mTargLocList.get(0).longitude;
            for (int i = 0; i < mTargLocList.size() - 1; i++) {
                LatLng point2 = mTargLocList.get(i);
                LatLng nextP = mTargLocList.get(i + 1);
                float direction = MapUtil.getDirection(point2, nextP);
                OverlayOptions options = new MarkerOptions().position(point2).icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow_r_up));
                Marker marker = (Marker) mBaiduMap.addOverlay(options);
                marker.setAnchor(0.5f, 0.5f);
                marker.setRotate(direction);
                drawLine(preTargLat, preTargLon, nextP.latitude, nextP.longitude, 0xaaff0000);
                preTargLat = nextP.latitude;
                preTargLon = nextP.longitude;
            }
            LatLng point = mTargLocList.get(mTargLocList.size() - 1);
            OverlayOptions options = new MarkerOptions().position(point).icon(BitmapDescriptorFactory.fromResource(R.drawable.target));
            Marker marker = (Marker) mBaiduMap.addOverlay(options);
            marker.setAnchor(0.5f, 0.5f);
            drawLine(preTargLat, preTargLon, point.latitude, point.longitude, 0xaaff0000);
        }
    }

    private void drawLine(double preLocLat, double preLocLon, double currentLat, double currentLon, int color) {
        //画连线
        LatLng pre = new LatLng(preLocLat, preLocLon);
        LatLng cur = new LatLng(currentLat, currentLon);
        List<LatLng> points = new ArrayList<>();
        points.add(pre);
        points.add(cur);
        OverlayOptions ooPolyLine = new PolylineOptions().width(10).color(color).points(points);
        mBaiduMap.addOverlay(ooPolyLine);
    }

    class RescueBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case Constant.RESCUE_PAUSE:
                    if (mMapView != null && mHandler != null && runnable != null) {
                        mMapView.onPause();
                        mHandler.removeCallbacks(runnable);
                    }
                    break;
                case Constant.RESCUE_RESUME:
                    if (pageFlage == Constant.FLAG_RESCUE) {
                        if (mMapView != null && mHandler != null && runnable != null) {
                            mMapView.onResume();
                            mHandler.postDelayed(runnable, 0);
                        }
                    }
                    break;
                case Constant.RESCUE_STOP:
                    if (mMapView != null && runnable != null && mHandler != null) {
                        mMapView.onPause();
                        mHandler.removeCallbacks(runnable);
                    }
                    break;
                case Constant.RESCUE_DESTROY:
                    mMapView.onDestroy();
                    mHandler.removeCallbacks(runnable);
                    runnable = null;
                    break;
                case Constant.TO_COUNT_PAGE:
                    pageFlage = intent.getIntExtra("flag", 0);
                    if (mMapView != null && mHandler != null && runnable != null) {
                        mMapView.onPause();
                        mHandler.removeCallbacks(runnable);
                    }
                    break;
                case Constant.TO_HISTORY_PAGE:
                    pageFlage = intent.getIntExtra("flag", 0);
                    if (mMapView != null && mHandler != null && runnable != null) {
                        mMapView.onPause();
                        mHandler.removeCallbacks(runnable);
                    }
                    break;
                case Constant.TO_RESCUE_PAGE:
                    pageFlage = intent.getIntExtra("flag", 0);
                    if (mMapView != null && runnable != null && mHandler != null) {
                        mMapView.onResume();
                        mHandler.postDelayed(runnable, 0);
                    }
                    break;
            }
        }
    }
}